package boardgamer.common.client.preference;

import android.content.SharedPreferences;
import android.preference.CheckBoxPreference;
import android.preference.EditTextPreference;
import android.preference.ListPreference;
import android.preference.PreferenceActivity;
import com.google.common.collect.ImmutableMap;

import static boardgamer.common.client.preference.RegisteredEnumIconList.IconRenderer;
import static boardgamer.common.client.preference.RegisteredEnumList.Renderer;
import static com.google.common.base.Preconditions.checkNotNull;

/**
 * @author garysoed
 */
public class PreferenceUpdater implements SharedPreferences.OnSharedPreferenceChangeListener {

  private final ImmutableMap<String, AbstractRegisteredPreference> registeredPreferences;
  
  private PreferenceUpdater(Builder builder) {
    this.registeredPreferences = builder.registeredPreferencesBuilder.build();
  }

  public void refreshAll() {
    for (AbstractRegisteredPreference registeredPreference : registeredPreferences.values()) {
      registeredPreference.refresh();
    }
  }

  @Override
  public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
    registeredPreferences.get(key).refresh();
  }

  public static class Builder {
    
    private ImmutableMap.Builder<String, AbstractRegisteredPreference> registeredPreferencesBuilder
        = ImmutableMap.builder();
    private final SharedPreferences sharedPreferences;
    private final PreferenceActivity preferenceActivity;

    public Builder(SharedPreferences sharedPreferences, PreferenceActivity activity) {
      this.sharedPreferences = checkNotNull(sharedPreferences, "sharedPreferences");
      this.preferenceActivity = checkNotNull(activity, "activity");
    }

    public <T> Builder registerEditText(String key, T defaultValue,
        StringConverter<T> preferenceConverter) {
      registeredPreferencesBuilder.put(key, new RegisteredEditText<T>(
          key,
          (EditTextPreference) preferenceActivity.findPreference(key),
          defaultValue,
          sharedPreferences,
          preferenceConverter));
      return this;
    }
    
    public Builder registerCheckBox(String key, boolean defaultValue) {
      registeredPreferencesBuilder.put(key, new RegisteredCheckBox(
          key,
          (CheckBoxPreference) preferenceActivity.findPreference(key),
          defaultValue,
          sharedPreferences));
      return this;
    }
    
    public <E extends Enum<E>> Builder registerEnumList(String key, E defaultValue,
        Class<E> clazz, StringConverter<E> stringConverter, Renderer<E> renderer) {
      registeredPreferencesBuilder.put(key, new RegisteredEnumList<E>(
          key, 
          (ListPreference) preferenceActivity.findPreference(key),
          defaultValue,
          clazz,
          sharedPreferences,
          stringConverter,
          renderer));
      return this;
    }
    
    public <E extends Enum<E>> Builder registerEnumIconList(String key, E defaultValue,
        Class<E> clazz, StringConverter<E> stringConverter, Renderer<E> renderer,
        IconRenderer<E> iconRenderer) {
      registeredPreferencesBuilder.put(key, new RegisteredEnumIconList<E>(
          key,
          (IconListPreference) preferenceActivity.findPreference(key),
          defaultValue,
          clazz,
          sharedPreferences,
          stringConverter,
          renderer,
          iconRenderer));
      return this;
    }
    
    public Builder register(String key, AbstractRegisteredPreference preference) {
      registeredPreferencesBuilder.put(key, preference);
      return this;
    }

    public PreferenceUpdater build() {
      PreferenceUpdater updater = new PreferenceUpdater(this);
      updater.refreshAll();
      return updater;
    }
  }
}
